#!/usr/bin/python2.4


import os
import subprocess
import sys
import time
import types


def quoted_array(a, quote="'", sep=', '):
  return sep.join('%s%s%s' % (quote, e, quote) for e in a)


def pformat_array(a, quote='', sep=' '):
  return '%d [%s]' % (len(a), quoted_array(a, quote, sep))


def parse_time(stime):
  # Equivalent to time.mktime(time.strptime(stime, '%Y-%m-%d %H:%M:%S'))
  return time.mktime(
      map(int, stime.replace('-', ' ').replace(':', ' ').split()) +
      [-1, -1, -1])


def human_time_span(seconds):
  seconds = int(seconds)
  if seconds < 60:
    return '%ss' % seconds
  if seconds < 100 * 60 * 60:
    minutes = seconds / 60
    h = minutes / 60
    m = minutes % 60
    parts = []
    if h:
      parts.append('%sh' % h)
    if m:
      parts.append('%sm' % m)
    return ''.join(parts)
  return '%sd' % (seconds / (24 * 60 * 60))


DELETE = object()

def update_dict(original, overrides):
  for key, value in overrides.iteritems():
    if value is DELETE:
      original.pop(key, None)
    else:
      original[key] = value
  return original


def sort_dicts(dicts, keys):

  def dict_sort_key(d):
    return [d[key] for key in keys]

  dicts.sort(key=dict_sort_key)


def sort_objects(objects, attrs):

  def object_sort_key(o):
    return [getattr(o, attr) for attr in attrs]

  objects.sort(key=object_sort_key)


def parse_filters(**dargs):
  results = []
  for key, value in dargs.iteritems():
    name_op_value = key.rsplit('__', 1)
    if len(name_op_value) == 1:
      name_op_value.append(None)
    name_op_value.append(value)
    results.append(name_op_value)
  return results


def nou_repr(value):
  if isinstance(value, (list, tuple, types.GeneratorType)):
    return '(%s)' % ','.join(nou_repr(v) for v in value)
  if isinstance(value, unicode):
    value = str(value)
  return repr(value)


def convert_to_sql(name, op, value):
  op_dict = {
    None: '=',
    'gt': '>',
    'gte': '>=',
    'lt': '<',
    'lte': '<=',
    'ne': '!=',
    'regex': 'REGEXP',
    'range': 'BETWEEN'
  }
  op = op_dict.get(op, op)
  if op in ('startswith', 'endswith', 'contains'):
    if op != 'startswith':
      value = '%' + value
    if op != 'endswith':
      value += '%'
    op = 'LIKE'

  if value is None:
    value = 'NULL'
    none_op_dict = {
      '=': 'IS',
      '!=': 'IS NOT'
    }
    op = none_op_dict.get(op, op)
  elif op.lower() == 'between':
    value ='%s AND %s' % (nou_repr(value[0]), nou_repr(value[1]))
  else:
    value = nou_repr(value)
  return '%s %s %s' % (name, op, value)


def mtime_and_size(filename):
  try:
    stats = os.stat(filename)
  except OSError:
    return None, None
  return stats.st_mtime, stats.st_size


def hostname_sort_key(hostname):
  return hostname


def execute(command):
  p = subprocess.Popen(command, stdin=file(os.devnull), stdout=subprocess.PIPE)
  if p.wait():
    raise AssertionError('command returned non-zero exit code: %d\n'
                         '%s\nstdout:\n%s' %
                         (p.returncode, ' '.join(command), p.stdout.read()))
  return p


def bisect_left(a, x, lo=0, hi=None, key=lambda x:x):
  if hi is None:
    hi = len(a)
  while lo < hi:
    m = (lo + hi) // 2
    if key(a[m]) >= x:
      hi = m
    else:
      lo = m + 1
  return hi


def bsearch(a, x, lo=0, hi=None, key=lambda x:x):
  if hi is None:
    hi = len(a)
  p = bisect_left(a, x, lo, hi, key)
  if p == hi or key(a[p]) != x:
    return None
  return a[p]


def import_site(global_dict):
  module_path = global_dict['__name__'].rsplit('.', 1)
  module_path[-1] = 'site_%s' % module_path[-1]
  module_name = '.'.join(module_path)

  try:
    __import__(module_name, global_dict)
  except ImportError:
    return False

  site_overrided = {}
  for key, value in vars(sys.modules[module_name]).iteritems():
    if not key.startswith('_'):
      if key not in global_dict or global_dict[key] is not value:
        if key in global_dict:
          site_overrided[key] = global_dict[key]
        global_dict[key] = value
  global_dict['_site_overrided'] = site_overrided
  return True


def get_site_overrided(global_dict, name):
  return global_dict.get('_site_overrided', {}).get(name, global_dict[name])


import_site(globals())
